package cn.ulc.socket.admin.service.staff.impl;

import cn.binarywang.wx.miniapp.api.WxMaQrcodeService;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.ulc.common.constant.PubDataConstant;
import cn.ulc.common.constant.enums.DeletedStatus;
import cn.ulc.common.exception.PlatformException;
import cn.ulc.common.model.param.PaginationParam;
import cn.ulc.common.util.AliyunOssFileUtil;
import cn.ulc.common.util.CommonUtil;
import cn.ulc.common.util.ConvertUtil;
import cn.ulc.socket.admin.common.BaseService;
import cn.ulc.socket.admin.model.dto.staff.RiderDTO;
import cn.ulc.socket.admin.model.dto.staff.StaffDTO;
import cn.ulc.socket.admin.model.dto.staff.StaffListDTO;
import cn.ulc.socket.admin.model.param.staff.StaffSaveParam;
import cn.ulc.socket.admin.service.staff.StaffServ;
import cn.ulc.store.dao.PubDataDao;
import cn.ulc.store.dao.staff.*;
import cn.ulc.store.entity.PubData;
import cn.ulc.store.entity.staff.*;
import lombok.AllArgsConstructor;
import org.beetl.sql.core.engine.PageQuery;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class StaffServImpl extends BaseService implements StaffServ {

    StaffDao staffDao;
    PubDataDao pubDataDao;
    StaffRoleDao staffRoleDao;
    StaffOrderDao staffOrderDao;
    StaffDeductDao staffDeductDao;
    StaffDeductBillDao staffDeductBillDao;
    WxMaService wxMaService;

    @Override
    public StaffListDTO findList(String key, PaginationParam pager) {
        Staff loginUser = getCurrentUser();
        Map<String,Object> condition = new HashMap<>();
        condition.put("key",key);
        condition.put("companyId",loginUser.getCompanyId());
        condition.put("loginUserId",loginUser.getId());
        PageQuery pageQuery = initPageQuery(pager);
        pageQuery.setParas(condition);
        staffDao.findListPage(pageQuery);
        List<Staff> list = pageQuery.getList();
        if(list != null && list.size()>0){
            List<StaffRole> roleList = staffRoleDao.findByCompany(loginUser.getCompanyId());
            if(roleList != null && roleList.size()>0){
                Map<Long,List<StaffRole>> map = roleList.parallelStream().collect(Collectors.groupingBy(StaffRole::getStaffId));
                list.stream().forEach(m->{
                    m.setRoleList(map.get(m.getId()));
                });
            }
        }
        return new StaffListDTO(list,pageQuery.getTotalRow());
    }
    @Override
    public StaffListDTO findRiderList(String key, PaginationParam pager) {
        Staff loginUser = getCurrentUser();
        String code = pubDataDao.findCodeByTypeAndName(PubDataConstant.DATA_TYPE_ROLE,"骑手");
        Map<String,Object> condition = new HashMap<>();
        condition.put("key",key);
        condition.put("role",code);
        condition.put("companyId",loginUser.getCompanyId());
        PageQuery pageQuery = initPageQuery(pager);
        pageQuery.setParas(condition);
        staffDao.findRiderListPage(pageQuery);
        return new StaffListDTO(pageQuery.getList(),pageQuery.getTotalRow());
    }

    @Override
    public StaffListDTO findListByIdentity(String key,String identity) {
        Staff loginUser = getCurrentUser();
        List<Staff> list = staffDao.findListByIdentity(key,identity, loginUser.getCompanyId());
        Long total = list != null?Convert.toLong(list.size(),0l) : 0;
        return new StaffListDTO(list, total);
    }

    @Override
    @Transactional
    public Staff save(StaffSaveParam param) {
        if(param == null) throw new PlatformException("未获取到表单信息");
        Staff loginUser = getCurrentUser();
        List<StaffRole> roleList = param.getRoleList();
        boolean isEdit = param.getId() != null && param.getId() > 0;
        Staff entity = null, check = null;
        if(isEdit) {   //编辑时
            entity = staffDao.findOne(param.getId());
            if (entity == null) throw new PlatformException("未获取到员工信息");
            // 检查角色,若之前是配送 ,存在未完成订单则需要处理后才能更改角色
            String code = pubDataDao.findCodeByTypeAndName(PubDataConstant.DATA_TYPE_ROLE,"骑手");
            if(StrUtil.isNotBlank(code)) {
                boolean oldContain = staffRoleDao.checkStaffContainRole(entity.getId(),code);
                if(oldContain) {
                    long paramContain = 0;
                    if(roleList != null && roleList.size()>0){
                        paramContain = roleList.stream().filter(m->code.equals(m.getRole())).count();
                    }
                    // 原来具有骑手角色,现在没有,检查下该员工是否有未处理订单
                    if (paramContain == 0) {
                        List<StaffOrder> orderList = staffOrderDao.findUnfinishedByStaff(entity.getId());
                        if (orderList != null && orderList.size() > 0) {
                            throw new PlatformException("员工[" + entity.getName() + "]还有未完成派单,不能取消其骑手角色,请处理派单后尝试");
                        }
                    }
                }
            }
        }else{
            entity = new Staff();
            check = staffDao.checkLoginName(param.getLoginName(),loginUser.getCompanyId());
            if(check != null && !check.getId().equals(entity.getId())) throw new PlatformException("员工登录名已被注册");
            entity.setLoginName(param.getLoginName());
            entity.setPassword(ConvertUtil.toMD5("666666"));
        }
        check = staffDao.checkPhone(param.getPhone(),loginUser.getCompanyId());
        if(check != null && !check.getId().equals(param.getId())) throw new PlatformException("员工手机号已被注册");

        setBaseInfo(entity);
        entity.setName(param.getName());
        entity.setPhone(param.getPhone());
        entity.setRemark(param.getRemark());
        staffDao.save(entity);

        //保存角色
        if(isEdit) staffRoleDao.deletedByStaff(entity.getId(), loginUser.getId());
        if(roleList != null && roleList.size()>0){
            for (StaffRole role : roleList) {
                setBaseInfo(role);
                role.setStaffId(entity.getId());
            }
            staffRoleDao.saveAll(roleList);
        }
        return entity;
    }

    @Override
    @Transactional
    public Staff saveRider(StaffSaveParam param) {
        if(param == null) throw new PlatformException("未获取到表单信息");
        Staff loginUser = getCurrentUser();
        boolean isEdit = param.getId() != null && param.getId() > 0;
        Staff entity = null, check = null;
        if(isEdit) {
            entity = staffDao.findOne(param.getId());
            if (entity == null) throw new PlatformException("未获取到骑手信息");
        }else{
            entity = new Staff();
//            check = staffDao.checkLoginName(param.getLoginName(),loginUser.getCompanyId());
//            if(check != null && !check.getId().equals(entity.getId())) throw new PlatformException("员工手机号已被注册");
            entity.setLoginName(param.getLoginName());
            entity.setPassword(ConvertUtil.toMD5("666666"));
        }
        check = staffDao.checkPhone(param.getPhone(),loginUser.getCompanyId());
        if(check != null && !check.getId().equals(param.getId())) throw new PlatformException("员工手机号已被注册");

        setBaseInfo(entity);
        entity.setName(param.getName());
        entity.setPhone(param.getPhone());
        entity.setRemark(param.getRemark());
        staffDao.save(entity);

        //保存角色
        if(!isEdit) {
            PubData rider = pubDataDao.findByTypeAndName(PubDataConstant.DATA_TYPE_ROLE,"骑手");
            if(rider == null) throw new PlatformException("骑手身份设置失败");
            StaffRole role = new StaffRole();
            setBaseInfo(role);
            role.setRole(rider.getCode());
            role.setRoleName(rider.getName());
            role.setStaffId(entity.getId());
            staffRoleDao.save(role);
        }
        return entity;
    }

    @Override
    public StaffDTO findDetail(Long id) {
        Staff entity = staffDao.findOne(id);
        List<StaffOrder> orderList = Collections.emptyList();
        List<StaffRole> roleList = Collections.emptyList();
        if(entity != null){
            orderList = staffOrderDao.findByStaff(entity.getId());
            roleList = staffRoleDao.findByStaff(entity.getId());
        }
        return StaffDTO.builder().model(entity).orderList(orderList).roleList(roleList).build();
    }

    @Override
    public Boolean deleted(Long id) {
        Staff entity = staffDao.findOne(id);
        if(entity != null){
            setBaseInfo(entity);
            entity.setDeleted(DeletedStatus.DELETED);
            staffDao.save(entity);
        }
        return true;
    }

    @Override
    public Boolean resetPassword(Long id) {
        Staff entity = staffDao.findOne(id);
        if(entity == null) throw new PlatformException("未获取到员工信息");
        setBaseInfo(entity);
        entity.setPassword(ConvertUtil.toMD5("666666"));
        staffDao.save(entity);
        return true;
    }

    @Override
    public Staff findOne(Long id) {
        return staffDao.findOne(id);
    }

    @Override
    public String generateQrCode(Long id) {
        String scene = id.toString();
        String page = "pages/user/bind";
        if(StrUtil.isBlank(scene)) throw new PlatformException("生成小程序码参数错误");
        WxMaQrcodeService wxMaQrcodeService = wxMaService.getQrcodeService();
        try{
            File qrCode = wxMaQrcodeService.createWxaCodeUnlimit(scene,page);
            String path = AliyunOssFileUtil.uploadPublicFile(qrCode, DateUtil.currentSeconds()+"","/store");
            return path;
        }catch (Exception e) {
            e.printStackTrace();
            throw new PlatformException("生成小程序异常");
        }
    }

    @Override
    public Boolean relieveQrCode(Long id) {
        long tid = Convert.toLong(id, 0l);
        Staff entity = staffDao.findOne(tid);
        if (entity == null) throw new PlatformException("未获取到员工信息");
        setBaseInfo(entity);
        entity.setWxUserId(null);
        staffDao.updateById(entity);
        return true;
    }

    @Override
    public Boolean checkBind(Long id) {
        long tid = Convert.toLong(id,0l);
        Staff entity = staffDao.findOne(tid);
        if(entity != null) {
            return entity.getWxUserId() != null;
        }
        return false;
    }
}
